#!/usr/bin/env bash 
set -e
set -x

##
## PARAMS
##

RELEASE_VERSION=${RELEASE_VERSION:-2.1.1.0}

SKAWARE_VERSION="2.0.4"
SKAWARE_RELEASE="${SKAWARE_VERSION}"
SKAWARE_SOURCE=${SKAWARE_SOURCE:-https://github.com/just-containers/skaware/releases/download/v$SKAWARE_RELEASE}

ENVDIR_VERSION="1.0.1"
ENVDIR_RELEASE="${ENVDIR_VERSION}-1"
ENVDIR_SOURCE=${ENVDIR_SOURCE:-https://github.com/just-containers/justc-envdir/releases/download/v$ENVDIR_RELEASE}

PREINIT_VERSION="1.0.5"
PREINIT_RELEASE="${PREINIT_VERSION}"
PREINIT_SOURCE=${PREINIT_SOURCE:-https://github.com/just-containers/s6-overlay-preinit/releases/download/v$PREINIT_RELEASE}

INSTALLER_VERSION="1.0.1"
INSTALLER_RELEASE="${INSTALLER_VERSION}-2"
INSTALLER_SOURCE=${INSTALLER_SOURCE:-https://github.com/just-containers/justc-installer/releases/download/v$INSTALLER_RELEASE}

MUSL_CROSS_MAKE_RELEASE=15
MUSL_CROSS_MAKE_SRC=${MUSL_CROSS_MAKE_SRC:-https://github.com/just-containers/musl-cross-make/releases/download/v$MUSL_CROSS_MAKE_RELEASE}

PWD=$(pwd)
TMP=${PWD}/tmp
DIST=${PWD}/dist
OVERLAY_SRC_PATH=${OVERLAY_SRC_PATH:-$PWD/overlay-rootfs}
OVERLAY_DST_PATH=${OVERLAY_DST_PATH:-$PWD/overlay-rootfs}

mkdir -p ${TMP}
mkdir -p ${DIST}

targets=( 'amd64' 'arm' 'armhf' 'x86' 'aarch64' 'ppc64le' )
editions=( '' 'nobin' )
gccs=(
'x86_64-linux-musl'
'arm-linux-musleabi'
'arm-linux-musleabihf'
'i486-linux-musl'
'aarch64-linux-musl'
'powerpc64le-linux-musl'
)

declare -A targets_gcc
targets_gcc[arm]=arm-linux-musleabi
targets_gcc[armhf]=arm-linux-musleabihf
targets_gcc[aarch64]=aarch64-linux-musl
targets_gcc[x86]=i486-linux-musl
targets_gcc[amd64]=x86_64-linux-musl
targets_gcc[ppc64le]=powerpc64le-linux-musl

generate_release() {
  printf "Binary releases include the following skaware packages:\n\n" > ${DIST}/release.md
  printf "| Software | Version |\n" >> ${DIST}/release.md
  printf "| -------- |:-------:|\n" >> ${DIST}/release.md

  while read -r line
  do
      package=`echo "${line}" | cut -d"=" -f1`
      version=`echo "${line}" | cut -d"=" -f2`
      if [ -n "${version}" ] ; then
        printf "| %s | %s |\n" "${package}" "${version}" >> ${DIST}/release.md
      fi
  done < ${DIST}/manifest.txt
  printf "\n" >> $DIST/release.md

  printf "Additionally, justc-envdir version %s\n" "${ENVDIR_VERSION}" >> ${DIST}/release.md
}

get_packages_with_versions_from_manifest() {
  # manifest
  manifest=$1

  # skaware versions manifest
  curl -R -L -o ${TMP}/manifest.txt ${SKAWARE_SOURCE}/$manifest

  # parse manifest into s6 associative array
  versions=()
  while read -r line
  do
      key=`echo "${line}" | cut -d"=" -f1`
      value=`echo "${line}" | cut -d"=" -f2`
      if [[ ! -z "${key}" && ! -z "${value}" ]]; then
          versions+=("${key}-${value}")
      fi
  done < ${TMP}/manifest.txt

  mv ${TMP}/manifest.txt ${DIST}/manifest.txt

  # output manifest as an array
  echo ${versions[@]}
}

##
## DOWNLOAD PACKAGES
##

# destination folder
cd ${TMP}

for gcc in "${gccs[@]}"; do
  curl -R -L -O ${MUSL_CROSS_MAKE_SRC}/gcc-7.3.0-${gcc}.tar.xz
  tar xf gcc-7.3.0-${gcc}.tar.xz
done

for target in "${targets[@]}"; do
  curl -R -L -O ${ENVDIR_SOURCE}/justc-envdir-${ENVDIR_VERSION}-linux-${target}.tar.gz
  curl -R -L -O ${PREINIT_SOURCE}/s6-overlay-preinit-${PREINIT_VERSION}-linux-${target}.tar.gz
  curl -R -L -O ${INSTALLER_SOURCE}/justc-installer-${INSTALLER_VERSION}-linux-${target}-dev.tar.gz
  tar xf justc-installer-${INSTALLER_VERSION}-linux-${target}-dev.tar.gz --strip-components=1 -C "${targets_gcc[$target]}"
done

packages=($(get_packages_with_versions_from_manifest "manifest-linux.txt"))
for package in "${packages[@]}"; do
  for target in "${targets[@]}"; do
    file=${package}-linux-${target}-bin.tar.gz
    curl -R -L -O ${SKAWARE_SOURCE}/$file
    file=${package}-linux-${target}-dev.tar.gz
    curl -R -L -O ${SKAWARE_SOURCE}/$file
    tar xf ${package}-linux-${target}-dev.tar.gz --strip-components=1 -C "${targets_gcc[$target]}"
  done
done


generate_release

##
## OVERLAYS
##

for edition in "${editions[@]}"; do
  for target in "${targets[@]}"; do
    # overlay path and dist file
    if [ "${edition}" == "nobin" ]; then
      overlaydstpath="$OVERLAY_DST_PATH-nobin"
      overlaytarpath="${DIST}/s6-overlay-nobin.tar"
    else
      overlaydstpath="$OVERLAY_DST_PATH-raw"
      overlaytarpath="${DIST}/s6-overlay-$target.tar"
    fi

    rm -rf $overlaydstpath
    rm -f  $overlaytarpath
    rm -f  $overlaytarpath.gz
    rm -f  payload.tar
    rm -f  payload.o
  
    # create overlay folder
    mkdir -p $overlaydstpath
    mkdir -p ${DIST}
  
    # copy overlay files
    cp -a $OVERLAY_SRC_PATH/. $overlaydstpath/
  
    if [ "${edition}" != "nobin" ]; then
      # skarnet versions manifest
      packages=($(get_packages_with_versions_from_manifest "manifest-linux.txt"))
  
      # install required binaries for this concrete output
      for package in "${packages[@]}"; do
        tar xvfz ${TMP}/$package-linux-$target-bin.tar.gz -C $overlaydstpath
      done
      tar xvfz ${TMP}/justc-envdir-${ENVDIR_VERSION}-linux-$target.tar.gz -C $overlaydstpath
      tar xvfz ${TMP}/s6-overlay-preinit-${PREINIT_VERSION}-linux-$target.tar.gz -C $overlaydstpath
    fi

    # create must exist directories
    mkdir -p $overlaydstpath/etc/s6/init/env-stage2
    mkdir -p $overlaydstpath/etc/{cont-init.d,cont-finish.d,fix-attrs.d,services.d}

    # fix perms for utilities
    chmod 0755 $overlaydstpath/usr/bin/fix-attrs
    chmod 0755 $overlaydstpath/usr/bin/logutil-{newfifo,service,service-main}
    chmod 0755 $overlaydstpath/usr/bin/printcontenv
    chmod 0755 $overlaydstpath/usr/bin/with-{contenv,retries,contenv-legacy}

    # fix init perms
    chmod 0755 $overlaydstpath/init
    chmod 0755 $overlaydstpath/etc/s6/init/init-*
    chmod 0755 $overlaydstpath/etc/s6/init-catchall/init-*
    chmod 0755 $overlaydstpath/etc/s6/init-no-catchall/init-*
    chmod 0755 $overlaydstpath/etc/s6/services/.s6-svscan/{crash,finish}
    chmod 0755 $overlaydstpath/etc/s6/services/s6-fdholderd/run
    chmod 0755 $overlaydstpath/etc/s6/services/s6-svscan-log/run

    # fix misc perms
    chmod 0755 $overlaydstpath/etc
    chmod 0755 $overlaydstpath/etc/{cont-init.d,cont-finish.d,fix-attrs.d,services.d}
    chmod 0755 $overlaydstpath/etc/s6
    chmod 0755 $overlaydstpath/etc/s6/{services,init-catchall,init-no-catchall,init}
    chmod 0755 $overlaydstpath/etc/s6/{init-catchall,init-no-catchall,init,services}
    chmod 0755 $overlaydstpath/etc/s6/init/{env,env-stage2}
    chmod 0755 $overlaydstpath/etc/s6/services/{.s6-svscan,s6-fdholderd,s6-svscan-log}
    chmod 0755 $overlaydstpath/etc/s6/services/s6-fdholderd/rules
    chmod 0755 $overlaydstpath/etc/s6/services/s6-fdholderd/rules/uid
    chmod 0755 $overlaydstpath/etc/s6/services/s6-fdholderd/rules/uid/{0,default}
    chmod 0755 $overlaydstpath/etc/s6/services/s6-fdholderd/rules/uid/0/env
    chmod 0755 $overlaydstpath/etc/s6/services/s6-fdholderd/rules/uid/default/env
    chmod 0755 $overlaydstpath/usr/bin

    if [ "${edition}" != "nobin" ]; then
        chmod 0755 $overlaydstpath/bin
        chmod 0755 $overlaydstpath/libexec

        # setuid for preinit
        chmod 4755 $overlaydstpath/bin/s6-overlay-preinit
    fi

    chmod 0644 $overlaydstpath/etc/s6/services/s6-fdholderd/notification-fd
    chmod 0644 $overlaydstpath/etc/s6/init/env/*
    chmod 0644 $overlaydstpath/etc/s6/init/init-stage2-fixattrs.txt

    # dist!
    tar --owner=root --group=root \
        -cvf                     \
        $overlaytarpath           \
        -C $overlaydstpath        \
        ./
    gzip -k $overlaytarpath

    # create installer
    if [ "${edition}" != "nobin" ] ; then
        mv $overlaytarpath payload.tar
        ${TMP}/bin/${targets_gcc[$target]}-ld -r -b binary payload.tar -o payload.o
        ${TMP}/bin/${targets_gcc[$target]}-gcc -static -o ${DIST}/s6-overlay-${target}-installer -ljustc_installer payload.o -lskarnet
    fi

  done
done

exit 0
